package com.usian.service.impl;

import ch.qos.logback.core.status.OnPrintStreamStatusListenerBase;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.usian.IDUtils;
import com.usian.PageResult;
import com.usian.mapper.*;
import com.usian.pojo.*;
import com.usian.redis.RedisClient;
import com.usian.service.ItemService;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class ItemServiceImpl implements ItemService {

    @Autowired
    private TbItemMapper tbItemMapper;

    @Autowired
    private TbItemDescMapper tbItemDescMapper;

    @Autowired
    private TbItemParamItemMapper tbItemParamItemMapper;

    @Autowired
    private TbItemCatMapper tbItemCatMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    private RedisClient redisClient;

    @Value("${ITEM_INFO}")
    private String ITEM_INFO;

    @Value("${BASE}")
    private String BASE;

    @Value("${DESC}")
    private String DESC;

    @Value("${PARAM}")
    private String PARAM;


    @Value("${ITEM_INFO_EXPIRE}")
    private Integer ITEM_INFO_EXPIRE;

    @Autowired
    private TbOrderItemMapper tbOrderItemMapper;

    @Override
    public TbItem findItemById(Long id) {

        //查询先查redis ，没有查库
        TbItem tbItem1  =(TbItem) redisClient.get(ITEM_INFO + ":" + id.toString() + ":" + BASE);
        if(tbItem1 !=null){
            return tbItem1;
        }

        TbItem tbItem =new TbItem();
        //防止redis缓存击穿 redis 分布式锁  setnx   100
        if(redisClient.setnx(ITEM_INFO+":"+id.toString()+":"+BASE+":NX","111",30)){

            //抢占redis资源
            //防止redis缓存穿透
            tbItem= tbItemMapper.selectByPrimaryKey(id);
            if(tbItem==null){
                redisClient.set(ITEM_INFO+":"+id.toString()+":"+BASE,new TbItem(1L,"redis为空"));
                redisClient.expire(ITEM_INFO+":"+id.toString()+":"+BASE,30);
            }else{
                //写入redis   item_info:3333:base -
                redisClient.set(ITEM_INFO+":"+id.toString()+":"+BASE,tbItem);
                redisClient.expire(ITEM_INFO+":"+id.toString()+":"+BASE,ITEM_INFO_EXPIRE);
            }
            //执行完毕释放锁
            redisClient.del(ITEM_INFO+":"+id.toString()+":"+BASE+":NX");
        }

        return tbItem;
    }

    @Override
    public PageResult selectTbItemAllByPage(Integer page, Integer rows) {

        PageHelper.startPage(page,rows);

        TbItemExample tbItemExample =new TbItemExample();
        TbItemExample.Criteria criteria = tbItemExample.createCriteria();
        criteria.andStatusEqualTo((byte)1);
        List<TbItem> list = tbItemMapper.selectByExample(tbItemExample);

        PageInfo<TbItem> pageInfo =new PageInfo<>(list);

        PageResult pageResult =new PageResult();
        pageResult.setPageIndex(pageInfo.getPageNum());
        pageResult.setTotalPage(pageInfo.getPages());
        pageResult.setResult(list);

        return pageResult;
    }

    @Override
    public Integer insertTbitem(TbItem tbItem, String desc, String itemParams) {

        //保存三张表
        //多个表保存的时候先保存主表   脏数据

        //tb_item
        long itemId = IDUtils.genItemId();
        tbItem.setId(itemId);
        tbItem.setStatus((byte)1);
        tbItem.setCreated(new Date());
        tbItem.setUpdated(new Date());
        int result = tbItemMapper.insertSelective(tbItem);  //1

        //tb_item_desc
        TbItemDesc tbItemDesc = new TbItemDesc();
        tbItemDesc.setItemId(itemId);
        tbItemDesc.setItemDesc(desc);
        tbItemDesc.setCreated(new Date());
        tbItemDesc.setUpdated(new Date());
        int result2 = tbItemDescMapper.insertSelective(tbItemDesc);


        //tb_item_param_item
        TbItemParamItem tbItemParamItem = new TbItemParamItem();
        tbItemParamItem.setItemId(itemId);
        tbItemParamItem.setParamData(itemParams);
        tbItemParamItem.setUpdated(new Date());
        tbItemParamItem.setCreated(new Date());
        int result3 = tbItemParamItemMapper.insertSelective(tbItemParamItem);

        //同步数据到es 发送mq消息  convertAndSend：1:交换机 exchange；2：路由规则 routingkey  3：消息内容  msg
        amqpTemplate.convertAndSend("exchange1","item.add",tbItem.getId());  //skuId

        if(result+result2+result3==3){
            //写入redis   item_info:3333:base -
            redisClient.set(ITEM_INFO+":"+tbItem.getId()+":"+BASE,tbItem);
            redisClient.set(ITEM_INFO+":"+tbItem.getId()+":"+DESC,tbItemDesc);
            redisClient.set(ITEM_INFO+":"+tbItem.getId()+":"+PARAM,tbItemParamItem);
        }

        return result+result2+result3;
    }


    @Override
    public Integer updateTbItem(TbItem tbItem, String desc, String itemParams) {

        //保存三张表
        //多个表保存的时候先保存主表   脏数据

        //tb_item
        tbItem.setStatus((byte)1);
        //tbItem.setCreated(new Date());
        tbItem.setUpdated(new Date());
        int result = tbItemMapper.updateByPrimaryKeySelective(tbItem); //1

        //tb_item_desc
        TbItemDesc tbItemDesc = new TbItemDesc();
        tbItemDesc.setItemId(tbItem.getId());
        tbItemDesc.setItemDesc(desc);
        //tbItemDesc.setCreated(new Date());
        tbItemDesc.setUpdated(new Date());
        int result2 = tbItemDescMapper.updateByPrimaryKeySelective(tbItemDesc);


        //tb_item_param_item
        TbItemParamItem tbItemParamItem = new TbItemParamItem();
        tbItemParamItem.setItemId(tbItem.getId());
        tbItemParamItem.setParamData(itemParams);
        tbItemParamItem.setUpdated(new Date());
        //tbItemParamItemMapper.updateByPrimaryKeySelective(tbItemParamItem);

        TbItemParamItemExample example =new TbItemParamItemExample();
        TbItemParamItemExample.Criteria criteria = example.createCriteria();
        criteria.andItemIdEqualTo(tbItem.getId());
        int result3 = tbItemParamItemMapper.updateByExampleSelective(tbItemParamItem,example);

        //同步数据到es 发送mq消息  convertAndSend：1:交换机 exchange；2：路由规则 routingkey  3：消息内容  msg
        amqpTemplate.convertAndSend("exchange1","item.update",tbItem.getId());

        if(result+result2+result3==3){
            //写入redis   item_info:3333:base -
            redisClient.set(ITEM_INFO+":"+tbItem.getId()+":"+BASE,tbItem);
            redisClient.set(ITEM_INFO+":"+tbItem.getId()+":"+DESC,tbItemDesc);
            redisClient.set(ITEM_INFO+":"+tbItem.getId()+":"+PARAM,tbItemParamItem);
        }

        return result+result2+result3;
    }

    @Override
    public Map<String, Object> preUpdateItem(Long itemId) {

        HashMap<String,Object> map =new HashMap<String, Object>();
        //item
        TbItem tbItem = tbItemMapper.selectByPrimaryKey(itemId);
        map.put("item",tbItem);

        //itemcat name
        TbItemCat itemCat = tbItemCatMapper.selectByPrimaryKey(tbItem.getCid());
        map.put("itemCat",itemCat.getName());

        //itemdesc
        TbItemDesc itemDesc = tbItemDescMapper.selectByPrimaryKey(tbItem.getId());

        map.put("itemDesc",itemDesc.getItemDesc());

        //itemparamitem
        TbItemParamItemExample example =new TbItemParamItemExample();
        TbItemParamItemExample.Criteria c = example.createCriteria();
        c.andItemIdEqualTo(itemId);
        List<TbItemParamItem> list = tbItemParamItemMapper.selectByExampleWithBLOBs(example);



        if(list.size()>0){
            map.put("itemParamItem",list.get(0).getParamData());
        }
        return map;
    }

    @Override
    public Integer deleteItemById(Long itemId){

        TbItemParamItemExample example =new TbItemParamItemExample();
        TbItemParamItemExample.Criteria c = example.createCriteria();
        c.andItemIdEqualTo(itemId);
        int result1 = tbItemParamItemMapper.deleteByExample(example);

        int result2 = tbItemDescMapper.deleteByPrimaryKey(itemId);

        TbItem tbItem =new TbItem();
        tbItem.setId(itemId);
        tbItem.setStatus((byte)3);
        tbItem.setUpdated(new Date());
        int result3 = tbItemMapper.updateByPrimaryKeySelective(tbItem);


        if(result1+result2+result3==3){
            //写入redis   item_info:3333:base -
            redisClient.set(ITEM_INFO+":"+tbItem.getId()+":"+BASE,tbItem);
            redisClient.del(ITEM_INFO+":"+tbItem.getId()+":"+DESC);
            redisClient.del(ITEM_INFO+":"+tbItem.getId()+":"+PARAM);
        }
        return result1+result2+result3;
    }

    @Override
    public TbItemDesc selectItemDescByItemId(Long itemId) {
        //查询先查redis ，没有查库
        TbItemDesc itemDesc1  =(TbItemDesc) redisClient.get(ITEM_INFO+":"+itemId.toString()+":"+DESC);
        if(itemDesc1 !=null){
            return itemDesc1;
        }

        TbItemDesc itemDesc =new TbItemDesc();
        //redis缓存击穿
        if(redisClient.setnx(ITEM_INFO+":"+itemId.toString()+":"+DESC+":nx",222,30)){
            itemDesc = tbItemDescMapper.selectByPrimaryKey(itemId);
            if(itemDesc==null){
                //写入redis   item_info:3333:base -
                redisClient.set(ITEM_INFO+":"+itemId.toString()+":"+DESC,new TbItemDesc(1L,"redis空值"));
                redisClient.expire(ITEM_INFO+":"+itemId.toString()+":"+DESC,30);
            }else{
                //写入redis   item_info:3333:base -
                redisClient.set(ITEM_INFO+":"+itemId.toString()+":"+DESC,itemDesc);
                redisClient.expire(ITEM_INFO+":"+itemId.toString()+":"+DESC,ITEM_INFO_EXPIRE);
            }

            redisClient.del(ITEM_INFO+":"+itemId.toString()+":"+DESC+":nx");
        }

        return itemDesc;
    }

    @Override
    public Integer updateTbItemByOrderId(String orderId) {
        TbOrderItemExample tbOrderItemExample = new TbOrderItemExample();
        TbOrderItemExample.Criteria criteria = tbOrderItemExample.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        List<TbOrderItem> tbOrderItemList =
                tbOrderItemMapper.selectByExample(tbOrderItemExample);
        int result = 0;
        for (int i = 0; i < tbOrderItemList.size(); i++) {
            TbOrderItem tbOrderItem =  tbOrderItemList.get(i);
            TbItem tbItem =tbItemMapper.selectByPrimaryKey(Long.valueOf(tbOrderItem.getItemId()));
            tbItem.setNum(tbItem.getNum()-tbOrderItem.getNum());
            result += tbItemMapper.updateByPrimaryKeySelective(tbItem);
        }
        return result;
    }


}
